﻿using Microsoft.AspNetCore.Http;
using Newtonsoft.Json.Linq;
using QBZ.Evaluation.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;

namespace QBZ.Evaluation.Domains.OAuth
{
    public class Wechat : LoginBase
    {
        static string authorize_url = "";
        static readonly string oauth_url = "https://api.weixin.qq.com/sns/oauth2/access_token";
        static readonly string user_info_url = "https://api.weixin.qq.com/sns/userinfo";
        static readonly string user_info_url_params = "access_token={0}&openid={1}&lang=zh_CN";
        string redirect_uri = "";
        public Wechat(HttpContext contextAccessor, string redirect = null, bool pc = true) : base(contextAccessor)
        {
            if (pc)
            {
                authorize_url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + LoginProvider.Wechat_client_id + "&redirect_uri={0}&response_type=code&scope=snsapi_login#wechat_redirect";
            }
            else
            {
                authorize_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + LoginProvider.Wechat_client_id + "&redirect_uri={0}&response_type=code&scope=snsapi_login#wechat_redirect";
            }
            if (redirect != null)
            {
                redirect_uri = redirect;
            }
            else
            {
                redirect_uri = contextAccessor.Request.Scheme + "://" + contextAccessor.Request.Host.Value + contextAccessor.Request.Path.Value;
            }
        }


        public ResponseModel Authorize()
        {
            var res = new ResponseModel(ErrReason.Ok);
            try
            {
                var code = AuthorizeCode;
                if (string.IsNullOrEmpty(code))
                {
                    Context.Response.Redirect(string.Format(authorize_url, redirect_uri), true);
                    return null;
                }
                else
                {
                    var errorMsg = string.Empty;
                    var token = Accesstoken(code, ref errorMsg);
                    if (token!=null)
                    {
                        res.result = UserInfo(token, ref errorMsg);
                        if (!string.IsNullOrEmpty(errorMsg))
                        {
                            res.status = new ResponseStatusModel
                            {
                                code = ErrReason.OAuthFailld,
                                msg = "OAuthGetInfoFaild " + errorMsg
                            };
                        }
                    }
                    else
                    {
                        res.status = new ResponseStatusModel
                        {
                            code = ErrReason.OAuthFailld,
                            msg = "OAuthFailld " + errorMsg
                        };
                    }
                }
            }
            catch (Exception ex)
            {
                res.status = new ResponseStatusModel
                {
                    code = ErrReason.UnknownError,
                    msg = ex.Message
                };
            }
            return res;
        }

        private OAuthModel Accesstoken(string code, ref string errMsg)
        {
            var data = new SortedDictionary<string, string>();
            data.Add("appid", LoginProvider.Wechat_client_id);
            data.Add("secret", LoginProvider.Wechat_client_secret);
            data.Add("grant_type", "authorization_code");
            data.Add("code", code);
            var Params = string.Join("&", data.Select(x => x.Key + "=" + x.Value).ToArray());
            using (var wb = new HttpClient())
            {
                try
                {
                    var response = wb.PostAsync(oauth_url, new StringContent(Params)).Result;
                    var result = response.Content.ReadAsStringAsync().Result;
                    var user = Deserialize(result);
                    return new OAuthModel {
                        Token = user.Value<string>("access_token"),
                        OpenId = user.Value<string>("openid"),
                    };
                }
                catch (Exception ex)
                {
                    errMsg = ex.Message;
                    return null;
                }
            }
        }

        private OAuthModel UserInfo(OAuthModel token, ref string errMsg)
        {
            try
            {
                //通过openid取用户信息
                var result = string.Empty;
                using (var wc = new HttpClient())
                {
                    var content = new StringContent(string.Format(user_info_url_params, token.Token, token.OpenId));
                    var response = wc.PostAsync(user_info_url, content).Result;
                    result = response.Content.ReadAsStringAsync().Result;
                }
                var user = Deserialize(result);

                var res = new OAuthModel
                {
                    City = user.Value<string>("city"),
                    FigureUrl = user.Value<string>("headimgurl"),
                    NickName = user.Value<string>("nickname"),
                    Province = user.Value<string>("province"),
                    Country = user.Value<string>("country"),
                    Sex = user.Value<int>("sex").ToString(),
                    Language = user.Value<string>("language"),
                    UnionId = user.Value<string>("unionid"),
                    Token = token.Token,
                    OAuthWay = OAuthWay.Wechat,
                    OpenId = token.OpenId,
                };
                return res;

            }
            catch (Exception ex)
            {
                errMsg = ex.Message;
                return null;
            }
        }
    }
}
